Agavi - Validation
Overview The validation system uses XML files to configure how input is validated. Validation is done before any action takes place. Where are they located? Module-specific validation classes are stored at %project_dir%/app/modules/%module_name%/lib/validators. The XML configuration files are stored at %project_dir%/app/modules/%module_name%/validate. Global validation classes are stored at %project_dir%/app/lib/validator. The XML configuration files has the following hierarchy: %project_dir%/app/config/validators.xml | | V %project_dir%/app/modules/%module_name%/config/validators.xml | | V %project_dir%/app/modules/%module_name%/validate/MyConfiguration.xml Putting the common validation rules in the parent configuration file(s) prevents us from repeating them over and over again. To set a configuration file's parent, simply define the parent attribute in : ... ... As an analogy, think of the configuration files in OOP terms: the parent XML files are like parent classes which child XML files inherit. How are they named? The filename for the XML file must be the same as your action name. For instance, if you are writing a validator for GatewaysEdit action, your XML file must be named as GatewaysEdit.xml. Writing a Validator # Write a class that extends the AgaviValidator class and implement a single method named validate(), that returns true on success and false on failure. # Edit %project_dir%/app/modules/%module_name%/config/autoload.xml so that your validation class will be automatically loaded. # ... Please refer to the built-in validation classes at %agavi_dir%/validator for examples. Writing an XML validation config file Read requests (HTTP GET) id Invalid ID. Write requests (HTTP POST) with simple validation class example In the X/HTML output: ... ... In the XML config file: ... form_element Default error message. The input is less than 3. The input is more than 8. ... In the MyValidator.class.php file: getData($this->getArgument()); if ($value < 3) { $this->throwError('min'); return false; } else if ($value > 8) { $this->throwError('max'); return false; } else { $this->throwError(); return false; } return true; } } ?> Whenever a validation error occurs, the previous wrong value and applicable error messages will be inserted into the XHTML output without any additional effort on your part: ... The input is more than 8. ... Cool, huh? Note that instead of directly using "this/is/an/example", it is generally a good idea to let Agavi generate the correct URL from the routes instead. My class name is too long. Can I use a shortcut? Yes. In fact, it's a good idea to map applicable validation classes to specific types of data: ... address Invalid IPv4 address. ... Definitions are usually defined in the parent XML configuration file. As an analogy, think of parent XML configuration files as header files that you #include in your C code. Definitions are like typedefs. Please refer to %agavi_dir%/config/defaults/validators.xml for examples. Form Population Filter Whenever a validation error occurs, Agavi automatically fills the form with the previous values. How does this work? Agavi treats the output as XML and manipulates it. It manipulates the structure of the form and appends the relevant error messages to the form elements. In light of this, the output has these restrictions: * The document must be a valid X/HTML. Unlike in HTML, incorrect markup will no longer work. * XML doesn't like HTML entities such as and © ** We need to use numerical entities instead (© => ©) ** General recommendation is to use the UTF-8 charset and use the actual character instead (i.e., use ©). As the world is getting smaller each day, we'll probably need to use Unicode to translate our products into different languages anyway. Quirks and Caveats Validating the Same Fields with "or" Class MyField MyField This is an error. Blah What happens: FooBar = success BlahBlah = failure MyField's value is returned to the action and everything proceeds as expected. FooBar = failure BlahBlah = success MyField's value is not returned to the action because the whole validation is marked as failure. TODO: put clearer explanation Solution Write a custom validator instead: MyField This is an error. Blah Links * Validation FAQ * Agavi Tip: Automatic Output of Validation Errors